package com.zhongli.devplatform.service.impl.sys;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhongli.devplatform.bean.SecurityUser;
import com.zhongli.devplatform.dto.sys.RoleDTO;
import com.zhongli.devplatform.mapper.sys.*;
import com.zhongli.devplatform.po.user.ReadMenuPO;
import com.zhongli.devplatform.po.user.ReadRolePO;
import com.zhongli.devplatform.query.sys.RoleQuery;
import com.zhongli.devplatform.service.imp.sys.ReadRoleService;
import com.zhongli.devplatform.utils.BeanCopierUtil;
import com.zhongli.devplatform.utils.user.UserUtil;
import com.zhongli.devplatform.vo.sys.RoleVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * @author  WuXiCheng
 * @date  2020/7/23 10:12
 * @version 1.0
 */
@Service
public class ReadRoleServiceImpl extends ServiceImpl<ReadRoleMapper, ReadRolePO> implements ReadRoleService {
    @Autowired
    private ReadRoleMapper roleMapper;

    @Autowired
    private ReadRoleMenuMapper roleMenuMapper;

    @Autowired
    private ReadMenuMapper menuMapper;

    @Autowired
    private ReadRoleResourceMapper readRoleResourceMapper;

    @Autowired
    private ReadRoleDeviceTypeMapper readRoleDeviceTypeMapper;


    @Override
    @Transactional
    public void save(RoleDTO roleDTO) {
        ReadRolePO rolePO = BeanCopierUtil.copy(roleDTO, ReadRolePO.class);
        if (rolePO.getId() == null) {
            roleMapper.insert(rolePO);
        } else {
            roleMapper.updateById(rolePO);
        }
        readRoleDeviceTypeMapper.deleteByRole(rolePO.getId());

        for (String deviceType : roleDTO.getDeviceTypes()) {
            readRoleDeviceTypeMapper.insert(rolePO.getId(), deviceType);
        }


    }

    @Override
    public void delete(Integer id) {
        roleMapper.deleteById(id);
    }

    @Override
    public Boolean isExist(RoleQuery query) {
        QueryWrapper queryWrapper = new QueryWrapper<ReadRolePO>();
        queryWrapper.eq("code", query.getCode());
        if (query.getId() != null) {
            queryWrapper.ne("id", query.getId());
        }
        return roleMapper.selectCount(queryWrapper) > 0;
    }

    @Override
    @Transactional
    public void saveRoleMenu(Integer roleId, List<Integer> menuIds) {
        List<ReadMenuPO> menuPOList = menuMapper.selectList(new QueryWrapper<ReadMenuPO>().select("parent_id").isNotNull("parent_id").in("id", menuIds));
        Set<Integer> parentIds = new HashSet();
        for (ReadMenuPO menuPO : menuPOList) {
            parentIds.add(menuPO.getParentId());
        }
        parentIds.addAll(menuIds);
        roleMenuMapper.deleteByRole(roleId);
        for (Integer menuId : parentIds) {
            roleMenuMapper.insert(roleId, menuId);
        }
    }

    @Override
    @Transactional
    public void saveRoleResource(Integer roleId, List<Integer> resourceIds) {
        readRoleResourceMapper.deleteByRole(roleId);
        for (Integer resourceId : resourceIds) {
            readRoleResourceMapper.insert(roleId, resourceId);
        }


    }

    @Override
    public Integer getRoleIdByCode(String code) {
        return roleMapper.selectOne(new QueryWrapper<ReadRolePO>().select("id").eq("code", code)).getId();
    }

    @Override
    public List<RoleVO> listCurrUserRole(String deviceType) {
        SecurityUser securityUser = UserUtil.getCurrUser();
        List<String> codes = new ArrayList<>();
        for (GrantedAuthority grantedAuthority : securityUser.getAuthorities()) {
            codes.add(grantedAuthority.getAuthority());
        }
        List<ReadRolePO> rolePOList = roleMapper.selectList(new QueryWrapper<ReadRolePO>()
                .select("id", "name")
                .in("code", codes)
                .inSql("id","select role_id from dev_platform_role_device_type where device_type = '"+deviceType+"'")
        );
        return BeanCopierUtil.copy(rolePOList, RoleVO.class);
    }

    @Override
    public List<String> listDeviceType(Integer roleId) {

        return readRoleDeviceTypeMapper.listDeviceType(roleId);
    }
    @Override
    public List<Integer> listRoleByDeviceType(String deviceType) {

        return readRoleDeviceTypeMapper.listRoleByDeviceType(deviceType);
    }
}
